'''
Author: didiplus
Date: 2025-01-20 15:12:50
LastEditTime: 2025-01-20 17:22:50
LastEditors: didiplus
Description: 
FilePath: \平台\清单&脚本\python脚本\generate_ansible_hosts.py
'''
import csv

def read_data_from_csv(file_path):
    data = []
    with open(file_path, 'r') as file:
        reader = csv.DictReader(file)
        for row in reader:
            data.append(row)
    return data

def group_data_by_subnet(data):
    grouped_data = {}
    for row in data:
        ip = row['IP']
        subnet = '.'.join(ip.split('.')[:3])
        if subnet not in grouped_data:
            grouped_data[subnet] = []
        grouped_data[subnet].append(row)
    return grouped_data

def sort_ips_in_group(grouped_data):
    for subnet, rows in grouped_data.items():
        grouped_data[subnet] = sorted(rows, key=lambda x: ip_to_int(x['IP']))
    return grouped_data

def ip_to_int(ip):
    parts = list(map(int, ip.split('.')))
    return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3]




def generate_ansible_hosts(grouped_data):
    ansible_hosts = []
    added_ips = set()  # 使用集合来存储已经添加的IP地址

    def add_ip_range(start, end):
        start_str = ip_to_str(start)
        end_str = ip_to_str(end)
        start_parts = start_str.split('.')
        end_parts = end_str.split('.')
        
        if start_parts[:3] == end_parts[:3]:
            if start == end:
                # 如果 start 和 end 相同，直接添加单个 IP 地址
                ansible_hosts.append(start_str)
            else:
                # 合并相同的前三个部分
                ansible_hosts.append(f"{start_parts[0]}.{start_parts[1]}.{start_parts[2]}.[{start_parts[3]}:{end_parts[3]}]")
        else:
            ansible_hosts.append(f"{start_str}")

    for subnet, rows in grouped_data.items():
        if not rows:
            continue  # 跳过空的子网

        ansible_hosts.append(f"[{subnet}]")
        current_range_start = None
        current_range_end = None

        for row in rows:
            try:
                ip = row['IP']
                ip_int = ip_to_int(ip)

                if ip_int not in added_ips:  # 检查IP地址是否已经添加过
                    if current_range_start is None:
                        current_range_start = ip_int
                        current_range_end = ip_int
                    elif ip_int == current_range_end + 1:
                        current_range_end = ip_int
                    else:
                        add_ip_range(current_range_start, current_range_end)
                        current_range_start = ip_int
                        current_range_end = ip_int
                    added_ips.add(ip_int)  # 将IP地址添加到集合中
                elif current_range_start is None or not (current_range_start <= ip_int <= current_range_end):
                    ansible_hosts.append(ip)

            except KeyError as e:
                print(f"Missing key in row data: {e}")
                continue

        if current_range_start is not None:
            add_ip_range(current_range_start, current_range_end)

        ansible_hosts.append(f"[{subnet}:vars]")
        try:
            ansible_hosts.append(f"ansible_ssh_user={rows[0]['Username']}")
            ansible_hosts.append(f"ansible_ssh_pass={rows[0]['Password']}")
            ansible_hosts.append(f"ansible_ssh_port={rows[0]['Port']}")
        except (KeyError, IndexError) as e:
            print(f"Error accessing vars for subnet {subnet}: {e}")
            continue

        ansible_hosts.append("")

    return ansible_hosts




def ip_to_str(ip_int):
    return f"{(ip_int >> 24) & 0xFF}.{(ip_int >> 16) & 0xFF}.{(ip_int >> 8) & 0xFF}.{ip_int & 0xFF}"

# 示例文件路径
file_path = 'test_data.csv'

# 从CSV文件读取数据
data = read_data_from_csv(file_path)

# 按网段分组数据
grouped_data = group_data_by_subnet(data)

# 对每个网段内的IP地址进行排序
grouped_data = sort_ips_in_group(grouped_data)

# 生成Ansible hosts清单
ansible_hosts = generate_ansible_hosts(grouped_data)

# 打印Ansible hosts清单
for host in ansible_hosts:
    print(host)
